/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dao;

import bentity.beCliente;
import bentity.beDetallePedido;
import bentity.beOrdenDespacho;
import bentity.bePedido;
import bentity.beProducto;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import visual.Seguridad.visualHelper;

/**
 *
 * @author renzo
 */
public class daoPedido {

    public int registrarPedido(bePedido pedido) throws Exception{
        String sql = "INSERT INTO PEDIDO (ID_PEDIDO, FECHA_PEDIDO,ID_CLIENTE,MONTO_TOTAL,ID_ORDEN_DESPACHO,FECHAENTREGA,ESTADOPEDIDO,FECHADESPACHO) VALUES (?,NOW(), ?, ?, NULL, ?, ?,NULL)";
        Connection conn = daoHelper.dameConexion();
        PreparedStatement ps = conn.prepareStatement(sql);
        int nextId = daoHelper.getNextId("PEDIDO", "ID_PEDIDO");
        ps.setInt(1,nextId);
        ps.setInt(2, pedido.getCliente().getIdCliente());
        ps.setDouble(3, pedido.getMontoTotal());
        ps.setDate(4, pedido.getFechaEntrega());
        ps.setInt(5,this.getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, conn));
        ps.executeUpdate();
        this.registrarDetallePedido(nextId,pedido.getDetallePedido(),conn);
        ps.close();
        conn.close();
        return daoHelper.TRANSACCION_EXITOSA;
    }

    private void registrarDetallePedido(int idPedido, ArrayList<beDetallePedido> detallePedido, Connection conn) throws Exception{
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        PreparedStatement ps = null;
        String sql = "";
        for(int i=0;i<detallePedido.size();i++){
            sql = "INSERT INTO DETALLE_PEDIDO (ID_DETALLE_PEDIDO,ID_PEDIDO,ID_PRODUCTO,CANTIDAD_PRODUCTO,SUBTOTAL) VALUES (?, ?, ?, ?, ?)";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, (i+1));
            ps.setInt(2, idPedido);
            ps.setInt(3, detallePedido.get(i).getIdProducto());
            ps.setInt(4, detallePedido.get(i).getCantProducto());
            ps.setDouble(5, detallePedido.get(i).getSubtotal());
            ps.executeUpdate();
        }
        ps.close();
        if (seAbrioConexion)
            conn.close();
    }

    public ArrayList<bePedido>  queryPedidosSinDetalleByFilters(beCliente clientePedido, beProducto productoPedido, double mtoMinimo, double mtoMaximo, Date fechaDesde, Date fechaHasta) throws Exception{
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        int []contador = new int[9];
        String sql = "SELECT A.*,B.RAZON_SOCIAL FROM PEDIDO A LEFT JOIN CLIENTE B ON (A.ID_CLIENTE = B.ID_CLIENTE) WHERE (A.ESTADOPEDIDO = ? OR A.ESTADOPEDIDO = ? OR A.ESTADOPEDIDO = ?) ";
        contador[0] = 1;
        contador[1] = 1;
        contador[2] = 1;
        if (clientePedido != null){
            sql += " AND A.ID_CLIENTE = ? ";
            contador[3] = 1;
        }
        if (productoPedido != null){
            sql += " AND ((SELECT COUNT(*) FROM DETALLE_PEDIDO WHERE ID_PRODUCTO = ? ) >= 1) ";
            contador[4] = 1;
        }
        if (mtoMinimo>0.0){
            sql += " AND A.MONTO_TOTAL >= ? ";
            contador[5] = 1;
        }
        if (mtoMaximo>0.0){
            sql += " AND A.MONTO_TOTAL <= ? ";
            contador[6] = 1;
        }
        if (fechaDesde != null){
            sql += " AND A.FECHA_PEDIDO >= CAST( ? AS DATE ) ";
            contador[7] = 1;
        }
        if (fechaHasta != null){
            sql += " AND A.FECHA_PEDIDO <= CAST( ? AS DATE) ";
            contador[8] = 1;
        }
        sql += " ORDER BY A.FECHA_PEDIDO ";
        conn = daoHelper.dameConexion();
        ps = conn.prepareStatement(sql);
        int j=0;
        for(int i=0; i<9; i++){
            if (contador[i]==1){
                j++;
                switch (i){
                    case 0:
                        ps.setInt(j,this.getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, conn));
                        break;
                    case 1:
                        ps.setInt(j,this.getEstadoPedidoEnBD(bePedido.P_POR_DESPACHAR, conn));
                        break;
                    case 2:
                        ps.setInt(j,this.getEstadoPedidoEnBD(bePedido.P_DESPACHADO, conn));
                        break;
                    case 3:
                        ps.setInt(j,clientePedido.getIdCliente());
                        break;
                    case 4:
                        ps.setInt(j,productoPedido.getIdProducto());
                        break;
                    case 5:
                        ps.setDouble(j,mtoMinimo);
                        break;
                    case 6:
                        ps.setDouble(j,mtoMaximo);
                        break;
                    case 7:
                        ps.setString(j,fechaDesde.toString());
                        break;
                    case 8:
                        ps.setString(j,fechaHasta.toString());
                        break;
                }
            }
        }
        rs = ps.executeQuery();
        ArrayList<bePedido> pedidos = new ArrayList<bePedido>();
        bePedido p = null;
        beCliente c = null;
        beOrdenDespacho od = null;
        int estadoPedido = -1;
        while (rs.next()){
            p = new bePedido();
            p.setIdPedido(rs.getInt(1));
            p.setFechaPedido(rs.getDate(2));
            c = new beCliente();
            c.setIdCliente(rs.getInt(3));
            c.setRazonSocial(rs.getString(9));
            p.setCliente(c);
            p.setMontoTotal(rs.getDouble(4));
            od = new beOrdenDespacho();
            p.setFechaEntrega(rs.getDate(5));
            estadoPedido = rs.getInt(6);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, conn))
                p.setEstadoPedido(bePedido.P_EN_PROCESO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_CANCELADO, conn))
                p.setEstadoPedido(bePedido.P_CANCELADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_DESPACHADO,conn))
                p.setEstadoPedido(bePedido.P_DESPACHADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_POR_DESPACHAR,conn))
                p.setEstadoPedido(bePedido.P_POR_DESPACHAR);
            od.setIdOrdenDespacho(rs.getInt(7));
            p.setOrdenDespacho(od);            
            p.setFechaDespacho(rs.getDate(8));
            pedidos.add(p);
        }
        rs.close();
        ps.close();
        conn.close();
        return pedidos;
    }

    public int getEstadoPedidoEnBD(int estadoPedido, Connection conn) throws Exception{
        PreparedStatement ps = null;
        ResultSet rs = null;
        int estado = -1;
        String sql = "SELECT ID_DATO FROM DATOS_COMBO WHERE NOMBRE_COMBO = 'EPEDID' ";
        if (estadoPedido == bePedido.P_EN_PROCESO)
            sql += "AND NOMBRE_DATO = 'En proceso'";
        if (estadoPedido == bePedido.P_CANCELADO)
            sql += "AND NOMBRE_DATO = 'Cancelado'";
        if (estadoPedido == bePedido.P_DESPACHADO)
            sql += "AND NOMBRE_DATO = 'Despachado'";
        if (estadoPedido == bePedido.P_POR_DESPACHAR)
            sql += "AND NOMBRE_DATO = 'Por despachar'";
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        if (rs.next())
            estado = rs.getInt(1);
        rs.close();
        ps.close();
        if (seAbrioConexion)
            conn.close();
        return estado;
    }

    public ArrayList<beDetallePedido> queryDetallePedidoById(int idPedido) throws Exception{
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        String sql = "SELECT A.ID_PRODUCTO, B.NOMBRE, A.CANTIDAD_PRODUCTO, A.SUBTOTAL FROM DETALLE_PEDIDO A LEFT JOIN PRODUCTO B ON (A.ID_PRODUCTO = B.ID_PRODUCTO) WHERE A.ID_PEDIDO = ? ORDER BY B.NOMBRE";
        conn = daoHelper.dameConexion();
        ps = conn.prepareStatement(sql);
        ps.setInt(1, idPedido);
        rs = ps.executeQuery();
        ArrayList<beDetallePedido> detalles = new ArrayList<beDetallePedido>();
        beDetallePedido d = null;
        while (rs.next()){
            d = new beDetallePedido();
            d.setIdProducto(rs.getInt(1));
            d.setNombreProducto(rs.getString(2));
            d.setCantProducto(rs.getInt(3));
            d.setSubtotal(rs.getDouble(4));
            detalles.add(d);
        }
        rs.close();
        ps.close();
        conn.close();
        return detalles;
    }

    public int modificarPedido(bePedido pedido) throws Exception{
        String sql = "UPDATE PEDIDO SET MONTO_TOTAL = ? , FECHAENTREGA = ? WHERE ID_PEDIDO = ?";
        Connection conn = daoHelper.dameConexion();
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setDouble(1,pedido.getMontoTotal());
        ps.setDate(2, pedido.getFechaEntrega());
        ps.setInt(3, pedido.getIdPedido());
        ps.executeUpdate();
        this.modificarDetallePedido(pedido.getIdPedido(),pedido.getDetallePedido(),conn);
        ps.close();
        conn.close();
        return daoHelper.TRANSACCION_EXITOSA;
    }

    private void modificarDetallePedido(int idPedido, ArrayList<beDetallePedido> detallePedido, Connection conn) throws Exception{
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        borrarDetallesPedido(idPedido, conn);
        PreparedStatement ps = null;
        String sql = "";
        for(int i=0;i<detallePedido.size();i++){
            sql = "INSERT INTO DETALLE_PEDIDO (ID_DETALLE_PEDIDO,ID_PEDIDO,ID_PRODUCTO,CANTIDAD_PRODUCTO,SUBTOTAL) VALUES (?, ?, ?, ?, ?)";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, i);
            ps.setInt(2, idPedido);
            ps.setInt(3, detallePedido.get(i).getIdProducto());
            ps.setInt(4, detallePedido.get(i).getCantProducto());
            ps.setDouble(5, detallePedido.get(i).getSubtotal());
            ps.executeUpdate();
        }
        ps.close();
        if (seAbrioConexion)
            conn.close();
    }

    private void borrarDetallesPedido(int idPedido, Connection conn) throws Exception{
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        String sql = "DELETE FROM DETALLE_PEDIDO WHERE ID_PEDIDO = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, idPedido);
        ps.executeUpdate();
        ps.close();
        if (seAbrioConexion)
            conn.close();
    }

    public int eliminarPedido(int idPedido) throws Exception{
        Connection conn = daoHelper.dameConexion();
        this.borrarDetallesPedido(idPedido, conn);
        String sql = "DELETE FROM PEDIDO WHERE ID_PEDIDO = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, idPedido);
        ps.executeUpdate();
        ps.close();
        return daoHelper.TRANSACCION_EXITOSA;
    }

    public void actualizarEstadoPedido(int idPedido, int estadoPedido, Connection conn) throws Exception{
        int estadoPedidoEnBD = this.getEstadoPedidoEnBD(estadoPedido, conn);
        String sql = "UPDATE PEDIDO SET ESTADOPEDIDO = ? WHERE ID_PEDIDO = ?";
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, estadoPedidoEnBD);
        ps.setInt(2, idPedido);
        ps.executeUpdate();
        if (seAbrioConexion)
            conn.close();
    }

    public void asignarOrdenDespacho(int idOrdenDespacho, int idPedido, Connection conn) throws Exception{
        String sql = "UPDATE PEDIDO SET ID_ORDEN_DESPACHO = ? WHERE ID_PEDIDO = ?";
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, idOrdenDespacho);
        ps.setInt(2, idPedido);
        ps.executeUpdate();
        if (seAbrioConexion)
            conn.close();
    }

    public ArrayList<bePedido> obtenerPedidosEnProceso() throws Exception{
        int estadoPedidoEnBD = this.getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, null);
        String sql = "SELECT A.*,C.RAZON_SOCIAL FROM PEDIDO A LEFT JOIN CLIENTE C ON (A.ID_CLIENTE = C.ID_CLIENTE) WHERE ESTADOPEDIDO = ?";
        Connection conn = daoHelper.dameConexion();
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, estadoPedidoEnBD);
        ResultSet rs = ps.executeQuery();
        int estadoPedido = -1;
        bePedido p = null;
        beCliente c = null;
        beOrdenDespacho od = null;
        ArrayList<bePedido> pedidos = new ArrayList<bePedido>();
        while (rs.next()){
            p = new bePedido();
            p.setIdPedido(rs.getInt(1));
            p.setFechaPedido(rs.getDate(2));
            c = new beCliente();
            c.setIdCliente(rs.getInt(3));
            c.setRazonSocial(rs.getString(9));
            p.setCliente(c);
            p.setMontoTotal(rs.getDouble(4));
            p.setFechaEntrega(rs.getDate(5));
            estadoPedido = rs.getInt(6);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, conn))
                p.setEstadoPedido(bePedido.P_EN_PROCESO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_CANCELADO, conn))
                p.setEstadoPedido(bePedido.P_CANCELADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_DESPACHADO,conn))
                p.setEstadoPedido(bePedido.P_DESPACHADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_POR_DESPACHAR,conn))
                p.setEstadoPedido(bePedido.P_POR_DESPACHAR);
            od = new beOrdenDespacho();
            od.setIdOrdenDespacho(rs.getInt(7));
            p.setOrdenDespacho(od);
            p.setFechaDespacho(rs.getDate(8));
            pedidos.add(p);
        }
        rs.close();
        ps.close();
        conn.close();
        return pedidos;
    }

    public ArrayList<bePedido> obtenerPedidosDisponibles(int idOrdenDespacho) throws Exception{
        int estadoPedidoEnBD = this.getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, null);
        String sql = "SELECT A.*,C.RAZON_SOCIAL FROM PEDIDO A LEFT JOIN CLIENTE C ON (A.ID_CLIENTE = C.ID_CLIENTE) WHERE ESTADOPEDIDO = ? OR ID_ORDEN_DESPACHO = ?";
        Connection conn = daoHelper.dameConexion();
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, estadoPedidoEnBD);
        ps.setInt(2, idOrdenDespacho);
        ResultSet rs = ps.executeQuery();
        int estadoPedido = -1;
        bePedido p = null;
        beCliente c = null;
        beOrdenDespacho od = null;
        ArrayList<bePedido> pedidos = new ArrayList<bePedido>();
        while (rs.next()){
            p = new bePedido();
            p.setIdPedido(rs.getInt(1));
            p.setFechaPedido(rs.getDate(2));
            c = new beCliente();
            c.setIdCliente(rs.getInt(3));
            c.setRazonSocial(rs.getString(9));
            p.setCliente(c);
            p.setMontoTotal(rs.getDouble(4));
            p.setFechaEntrega(rs.getDate(5));
            estadoPedido = rs.getInt(6);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_EN_PROCESO, conn))
                p.setEstadoPedido(bePedido.P_EN_PROCESO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_CANCELADO, conn))
                p.setEstadoPedido(bePedido.P_CANCELADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_DESPACHADO,conn))
                p.setEstadoPedido(bePedido.P_DESPACHADO);
            if (estadoPedido == (new daoPedido()).getEstadoPedidoEnBD(bePedido.P_POR_DESPACHAR,conn))
                p.setEstadoPedido(bePedido.P_POR_DESPACHAR);
            od = new beOrdenDespacho();
            od.setIdOrdenDespacho(rs.getInt(7));
            p.setOrdenDespacho(od);
            p.setFechaDespacho(rs.getDate(8));
            pedidos.add(p);
        }
        rs.close();
        ps.close();
        conn.close();
        return pedidos;
    }

    public ArrayList<bePedido> queryPedidosOrdenByID(int idOrdenDespacho, Connection conn) throws Exception{
        String sql = "SELECT A.ID_PEDIDO, C.ID_CLIENTE, C.RAZON_SOCIAL, A.FECHA_PEDIDO, A.FECHAENTREGA FROM PEDIDO A LEFT JOIN CLIENTE C ON (A.ID_CLIENTE = C.ID_CLIENTE) WHERE A.ID_ORDEN_DESPACHO = ?";
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, idOrdenDespacho);
        ResultSet rs = ps.executeQuery();
        ArrayList<bePedido> pedidos = new ArrayList<bePedido>();
        bePedido p = null;
        beCliente c = null;
        while(rs.next()){
            p = new bePedido();
            p.setIdPedido(rs.getInt(1));
            c = new beCliente();
            c.setIdCliente(rs.getInt(2));
            c.setRazonSocial(rs.getString(3));
            p.setCliente(c);
            p.setFechaPedido(rs.getDate(4));
            p.setFechaEntrega(rs.getDate(5));
            pedidos.add(p);
        }
        rs.close();
        ps.close();
        if (seAbrioConexion)
            conn.close();
        return pedidos;
    }

    public void actualizarOrdenPedidoNulo(int idOrdenDespacho, Connection conn) throws Exception{
        String sql = "UPDATE PEDIDO SET ID_ORDEN_DESPACHO = NULL WHERE ID_ORDEN_DESPACHO = ?";
        boolean seAbrioConexion = false;
        if (conn == null){
            conn = daoHelper.dameConexion();
            seAbrioConexion = true;
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, idOrdenDespacho);
        ps.executeUpdate();
        if (seAbrioConexion)
            conn.close();
    }

    public ArrayList<beProducto> obtenerProductosDePedidos(ArrayList<bePedido> pedidos) throws Exception{
        ArrayList<beProducto> productos = new ArrayList<beProducto>();
        return productos;
    }
}
